package uk.ac.glasgow.demosocs.impl.election;

import uk.ac.glasgow.demosocs.impl.election.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashSet;
import java.util.Set;

public class ElectionStoreImpl {

	private File file;
	// map collection of the electionImpl objects, key is election id, value is
	private Set<ElectionImpl> mElections;

	/**
	 * initialization of Elections collection basedon the file name providing
	 * 
	 * @param fileName
	 *            - name of the file in same folder
	 */
	public ElectionStoreImpl(String fileName) {
	
		mElections = new HashSet<ElectionImpl>();

		file = new File(fileName);
		if (file.exists()) {
			// loading the file
			loadFromAFile(file);
		} else
			// no
			saveElectionsToFile();
	}

	/**
	 * can load a election collection from a file
	 * 
	 * @param fileName
	 *            - the name of the file
	 * @return true for successfully load from the file
	 * @throws  
	 */
	public void loadFromAFile(File file) {
		// loading the election collection from the file
		if (file.exists()) {
			try {
				FileInputStream fileIn = new FileInputStream(file);
				ObjectInputStream objectin = new ObjectInputStream(fileIn);

				// get the election collection and stored as a member
				mElections = (HashSet<ElectionImpl>) objectin.readObject();

				// close streams after use
				objectin.close();
				fileIn.close();

			} catch (FileNotFoundException e) {
				System.err.println(e.toString());
				removeFileAndCreateNewFile();
			}  catch (ClassNotFoundException e) {
				e.printStackTrace();
				removeFileAndCreateNewFile();
			} catch (IOException e) {
				e.printStackTrace();
				removeFileAndCreateNewFile();

			} 
		}// end if
	}

	/**
	 * add a election to the collection
	 * 
	 * @param election
	 *            - electionImpl object
	 */
	public void addElectionImpl(ElectionImpl election) {
		try{
		if(containsEID(election.getEID())){
		
		} else{
			
			// add the election to the collection
			mElections.add(election);
			// save the election to file every time add a new election
			saveElectionsToFile();
		}
		}catch(NullPointerException e){
			System.err.println("Election without election id can not be added to storage.");
		}
	}

	/**
	 * get a electionImpl object by the election id
	 * 
	 * @param ElectionId
	 * @return electionimpl object
	 */
	public ElectionImpl getElectionImpl(String ElectionId) {
		// find the electionimpl object by election id
		for (ElectionImpl e : mElections) {
			if (e.getEID().equals(ElectionId)) {
				return e;
			}
		}
		// if not found election id in the collection
		System.err.println("The election id does not exist in storage!");
		return null;
	}

	/**
	 * save the collection to  file as the filename
	 */
	public void saveElectionsToFile() {
		try {
			
			FileOutputStream fileOut = new FileOutputStream(file);
			ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);

			// write the election hashmap object to file
			objectOut.writeObject(mElections);

			// close streams
			objectOut.close();
			fileOut.close();
		} catch (FileNotFoundException e) {
			System.err.println(e.toString());
			file = new File("Election_database");
			saveElectionsToFile();
		} catch (IOException e) {
			e.printStackTrace();
			removeFileAndCreateNewFile();
		} 
	}

	/**
	 * get the electionimpl collection
	 * @return Set<ElectionImpl> collection
	 */
	public Set<ElectionImpl> getTheElections(){
		return mElections;
	}
	
	/**
	 * remove the election from collection
	 * @param electionId
	 */
	public void removeElection(String electionId){
		mElections.remove(getElectionImpl(electionId));
		
		saveElectionsToFile();
	}
	
	public boolean containsEID(String eid){
		boolean con = false;
		for(ElectionImpl ele : mElections){
			if(eid.equals(ele.getEID()))
				con = true; 
		}
		
		return con;
	}
	public void cleanElectionStoreAndCreateNewFile(){
		mElections = new HashSet<ElectionImpl>();
		saveElectionsToFile();
	}
	private void removeFileAndCreateNewFile(){
		file.delete();
		saveElectionsToFile();
	}
}
